﻿using System;
using System.Collections.Generic;
using Cesave.Application.Permisos.SynchronizationService;
using Microsoft.Synchronization;
using System.ComponentModel;
using Cesave.Infrastructure.CrossCutting.IoC;
using Cesave.Infrastructure.CrossCutting.Logging;
using Cesave.Infrastructure.CrossCutting.Network;
using Cesave.DistributedServices.PermisosModule.WindowsHost.Models;
using Microsoft.Synchronization.Data;
using Infragistics.Win.UltraWinGrid;

namespace Cesave.DistributedServices.PermisosModule.WindowsHost.ViewModels.Main
{
    public partial class MainViewModel
    {
        #region Private properties

        private ISynchronizationAgent _synchronizationAgent;
        private bool _closeAfterSynchronization = default(bool);
        private List<SynchronizationSummary> _synchronizationSummaries;
        private int _synchronizationCounter = default(int);

        #endregion

        #region Public properties

        public List<SynchronizationSummary> SynchronizationSummaries
        {
            get
            {
                if (_synchronizationSummaries == null)
                    _synchronizationSummaries = new List<SynchronizationSummary>();
                return _synchronizationSummaries;
            }
            private set
            {
                _synchronizationSummaries = value;
                if (_synchronizationSummaries != null)
                {
                    RaisePropertyChanged("SynchronizationSummaries");
                }
            }
        }

        #endregion

        #region Event methods

        private void SynchronizationSummariesPropertyChanged()
        {
            _view.synchronizationSummaryBindingSource.DataSource = SynchronizationSummaries;
            _view.synchronizationSummaryGrid.Rows.Refresh(RefreshRow.ReloadData, true);
        }

        private void Synchronize(object sender, DoWorkEventArgs e)
        {
            try
            {
                _synchronizationAgent = new SynchronizationAgent();
                _synchronizationAgent.SynchronizationProgressChanged += NotifyOnSynchronizationStateChanged;
                _synchronizationAgent.Synchronize();
                e.Result = _synchronizationAgent.SynchronizationStatistics;
            }
            catch (SyncException ex)
            {
                ITraceManager traceManager = IoCFactory.Resolve<ITraceManager>();
                traceManager.TraceCritical(ex.Message);
            }
        }

        private void CheckSynchronization(object sender, EventArgs e)
        {
            if (_view.synchronizationBackgroundWorker.IsBusy)
                return;
            INetworkHelper networkHelper = IoCFactory.Resolve<INetworkHelper>();
            if (!networkHelper.IsConnectedToInternet)
                if (!networkHelper.IsConnectedToSynchronizationServer)
                    return;
                else
                    if (!networkHelper.IsConnectedToSynchronizationServer)
                        return;
            _view.synchronizationBackgroundWorker.RunWorkerAsync();
        }

        private void NotifyOnSynchronizationStateChanged(object sender, SessionProgressEventArgs e)
        {
            int synchronizationPercentageCompleted = e.PercentCompleted;
            string synchronizationStateMessage = e.SyncStage.ToString();
            switch (e.SyncStage)
            {
                case SyncStage.ApplyingDeletes:
                    break;
                case SyncStage.ApplyingInserts:
                    break;
                case SyncStage.ApplyingUpdates:
                    break;
                case SyncStage.CreatingMetadata:
                    break;
                case SyncStage.CreatingSchema:
                    break;
                case SyncStage.DeletingMetadata:
                    break;
                case SyncStage.DownloadingChanges:
                    break;
                case SyncStage.GettingDeletes:
                    break;
                case SyncStage.GettingInserts:
                    break;
                case SyncStage.GettingUpdates:
                    break;
                case SyncStage.ReadingMetadata:
                    break;
                case SyncStage.ReadingSchema:
                    break;
                case SyncStage.UploadingChanges:
                    break;
                case SyncStage.WritingMetadata:
                    break;
                default:
                    break;
            }
            _view.synchronizationBackgroundWorker.ReportProgress(synchronizationPercentageCompleted, synchronizationStateMessage);
        }

        private void NotifySynchronizationSummary(object sender, RunWorkerCompletedEventArgs e)
        {
            if (!e.Cancelled && e.Error == null)
            {
                SyncStatistics statistics = e.Result as SyncStatistics;
                if (statistics != null)
                {
                    _synchronizationCounter++;
                    int totalChangesUploaded = _synchronizationAgent.SynchronizationStatistics.TotalChangesUploaded;
                    int totalChangesDownloaded = _synchronizationAgent.SynchronizationStatistics.TotalChangesDownloaded;
                    DateTime startTime = _synchronizationAgent.SynchronizationStatistics.SyncStartTime;
                    DateTime completeTime = _synchronizationAgent.SynchronizationStatistics.SyncCompleteTime;
                    TimeSpan totalTime = (startTime - completeTime);
                    SynchronizationSummary summary = new SynchronizationSummary()
                    {
                        CompleteTime = completeTime,
                        StartTime = startTime,
                        SynchronizationCount = _synchronizationCounter,
                        TotalChangesDownloaded = totalChangesDownloaded,
                        TotalChangesUploaded = totalChangesUploaded,
                        TotalTime = totalTime,
                    };
                    SynchronizationSummaries.Add(summary);
                    _view.synchronizationSummaryBindingSource.DataSource = SynchronizationSummaries;
                    _view.synchronizationSummaryGrid.Rows.Refresh(RefreshRow.ReloadData, true);
                }
            }
            else
            {
                if (e.Error != null)
                {
                    ITraceManager traceManager = IoCFactory.Resolve<ITraceManager>();
                    traceManager.TraceCritical(e.Error.Message);
                }
            }
            if (_closeAfterSynchronization)
                System.Windows.Forms.Application.Exit();
        }

        #endregion

    }
}
